home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / vol16n13.zip / ATLCTL.ZIP / AtlEditCtl.h < prev    next >
C/C++ Source or Header  |  1997-01-29  |  17KB  |  601 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // PC Magazine ActiveX Validated Edit Control
  3. // First appeared in PC Magazine, US Edition, ... 
  4. //
  5. // Written by John Lam
  6.  
  7. // AtlEditCtl.h : Declaration of the CAtlEditCtl
  8.  
  9. #ifndef __ATLEDITCTL_H_
  10. #define __ATLEDITCTL_H_
  11.  
  12. #include "resource.h"       // main symbols
  13. #include "CPAtlEdit10.h"    // our CProxy_AtlEditCtlEvents implementation
  14.  
  15. // Declarations for our system OLE_COLOR values
  16.  
  17. const int OLE_COLOR_WINDOW_BACKGROUND = 0x80000005;
  18. const int OLE_COLOR_WINDOW_TEXT = 0x80000008;
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CAtlEditCtl
  22. class ATL_NO_VTABLE CAtlEditCtl : 
  23.  
  24.     public CComObjectRootEx<CComObjectThreadModel>,
  25.     public CComCoClass<CAtlEditCtl, &CLSID_AtlEditCtl>,
  26.     public CComControl<CAtlEditCtl>,
  27.     public CStockPropImpl<CAtlEditCtl, IAtlEditCtl, &IID_IAtlEditCtl, &LIBID_ATLEDIT10Lib>,
  28.  
  29.     // We changed parameter 2 from NULL in the default implementation to 
  30.     // DIID_AtlEditCtlEvents to specify the outgoing interface for our events
  31.  
  32.     public IProvideClassInfo2Impl<&CLSID_AtlEditCtl, &DIID__AtlEditCtlEvents, &LIBID_ATLEDIT10Lib>,
  33.     public IPersistStreamInitImpl<CAtlEditCtl>,      
  34.     public IPersistStorageImpl<CAtlEditCtl>,
  35.     public IQuickActivateImpl<CAtlEditCtl>,
  36.     public IOleControlImpl<CAtlEditCtl>,
  37.     public IOleObjectImpl<CAtlEditCtl>,
  38.     public IOleInPlaceActiveObjectImpl<CAtlEditCtl>,
  39.     public IViewObjectExImpl<CAtlEditCtl>,
  40.     public IOleInPlaceObjectWindowlessImpl<CAtlEditCtl>,
  41.     public IDataObjectImpl<CAtlEditCtl>,
  42.     public ISpecifyPropertyPagesImpl<CAtlEditCtl>,
  43.  
  44.     // We added these two additional classes to our inheritance list
  45.     // so that our control can now support outgoing events
  46.  
  47.     public CProxy_AtlEditCtlEvents<CAtlEditCtl>,
  48.     public IConnectionPointContainerImpl<CAtlEditCtl>,
  49.  
  50.     // This line is required for VB5
  51.  
  52.     public IPropertyNotifySinkCP<CAtlEditCtl>
  53. {
  54. public:
  55.  
  56.     CContainedWindow m_ctlEdit;
  57.     
  58.     CAtlEditCtl() :    
  59.         m_ctlEdit(_T("Edit"), this, 1), m_hFontPrev( 0 )
  60.     {
  61.          m_bWindowOnly = TRUE; 
  62.     }
  63.  
  64. DECLARE_REGISTRY_RESOURCEID(IDR_ATLEDITCTL)
  65.  
  66. BEGIN_COM_MAP(CAtlEditCtl)
  67.     COM_INTERFACE_ENTRY(IAtlEditCtl)
  68.     COM_INTERFACE_ENTRY(IDispatch)
  69.     COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
  70.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
  71.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
  72. //    COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)
  73.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)
  74.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
  75.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
  76.     COM_INTERFACE_ENTRY_IMPL(IOleControl)
  77.     COM_INTERFACE_ENTRY_IMPL(IOleObject)
  78.     COM_INTERFACE_ENTRY_IMPL(IQuickActivate)
  79.     COM_INTERFACE_ENTRY_IMPL(IPersistStorage)
  80.     COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)
  81.     COM_INTERFACE_ENTRY_IMPL(ISpecifyPropertyPages)
  82.     COM_INTERFACE_ENTRY_IMPL(IDataObject)
  83.     COM_INTERFACE_ENTRY(IProvideClassInfo)
  84.     COM_INTERFACE_ENTRY(IProvideClassInfo2)
  85.  
  86.     // We added this line to add the IConnectionPointContainer interface
  87.     // to the list of interfaces that the container can QI for
  88.  
  89.     COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
  90. END_COM_MAP()
  91.  
  92. BEGIN_PROPERTY_MAP(CAtlEditCtl)
  93.     PROP_ENTRY( "Back Color", DISPID_BACKCOLOR, CLSID_StockColorPage )
  94.     PROP_ENTRY( "Fore Color", DISPID_FORECOLOR, CLSID_StockColorPage )
  95.     PROP_ENTRY( "Error Color", 0, CLSID_StockColorPage )
  96.     PROP_PAGE(CLSID_StockColorPage)
  97. END_PROPERTY_MAP()
  98.  
  99. // We add a connection point map so that ATL (specifically, IConnectionPointContainerImpl)
  100. // knows about our outgoing interface. We also needed to add the IPropertyNotifySink
  101. // outgoing interface so that the control works properly in VB5.
  102.  
  103. BEGIN_CONNECTION_POINT_MAP(CAtlEditCtl)
  104.     CONNECTION_POINT_ENTRY(DIID__AtlEditCtlEvents)
  105.     CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
  106. END_CONNECTION_POINT_MAP()
  107.  
  108. BEGIN_MSG_MAP(CAtlEditCtl)
  109.  
  110.     MESSAGE_HANDLER(WM_PAINT, OnPaint)
  111.     MESSAGE_HANDLER(WM_GETDLGCODE, OnGetDlgCode)
  112.     MESSAGE_HANDLER(WM_CREATE, OnCreate)
  113.     MESSAGE_HANDLER(WM_SETFOCUS, OnOleControlSetFocus)
  114.     MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
  115.  
  116.     // Our message handler to tell the edit control what colors to
  117.     // use for the foreground and background colors
  118.  
  119.     MESSAGE_HANDLER(WM_CTLCOLOREDIT, OnCtlColorEdit)
  120.  
  121. ALT_MSG_MAP(1)
  122.  
  123.     // We have to add these message handlers for the set focus and
  124.     // lost (kill) focus messages. The lost focus handler fires the
  125.     // validation event.
  126.  
  127.     MESSAGE_HANDLER(WM_KILLFOCUS, OnSubclassKillFocus)
  128. //    MESSAGE_HANDLER(WM_CHAR, OnChar)
  129.  
  130. END_MSG_MAP()
  131.  
  132.     ///////////////////////////////////////////////////////////////////////////
  133.     // Helper functions
  134.  
  135.     // This is a helper function that handles changing the edit control's font
  136.     // when the font changes.
  137.  
  138.     HRESULT OnFontChanged()
  139.     {
  140.         HFONT hFont;
  141.  
  142.         // We only change the font if we are in run-time mode (i.e. there is a
  143.         // edit control window - which doesn't exist at design time)
  144.  
  145.         if( IsWindow( m_ctlEdit ) )
  146.         {
  147.             if( m_Font == NULL )
  148.             {
  149.                 // A serious failure. Make sure that we don't have a selected font
  150.                 // in our control
  151.  
  152.                 m_ctlEdit.SendMessage( WM_SETFONT, 0, 0 );
  153.                 m_hFontPrev = 0;
  154.             
  155.                 return E_FAIL;
  156.             }
  157.  
  158.             if( FAILED( m_Font->get_hFont( &hFont ) ) )
  159.                 return E_FAIL;
  160.  
  161.             // Addref this font
  162.  
  163.             m_Font->AddRefHfont( hFont );
  164.             m_ctlEdit.SendMessage( WM_SETFONT, (WPARAM) hFont, 0 );
  165.  
  166.             // See if there was a previous font
  167.  
  168.             if( m_hFontPrev != NULL )
  169.             {
  170.                 // Yes there was, so let's release that font from our font object
  171.  
  172.                 m_Font->ReleaseHfont( hFont );
  173.                 m_hFontPrev = hFont;
  174.             }
  175.         }
  176.  
  177.         return S_OK;
  178.     }
  179.  
  180.     ///////////////////////////////////////////////////////////////////////////
  181.     // General windows message handlers
  182.  
  183.     // Pass along the appropriate control messages to the default windows
  184.     // message handler
  185. /*
  186.     LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  187.     {
  188.         if( static_cast< TCHAR >( wParam ) == VK_TAB )
  189.         {
  190.             CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  191.  
  192.             MSG msg;
  193.             HRESULT hr;
  194.  
  195.             msg.hwnd = m_ctlEdit;
  196.             msg.message = WM_KEYDOWN;
  197.             msg.wParam = static_cast< WPARAM >( VK_TAB );
  198.             msg.lParam = 0;
  199.  
  200.             BOOL bShift = (GetKeyState(VK_SHIFT) < 0);
  201.             BOOL bCtrl  = (GetKeyState(VK_CONTROL) < 0);
  202.             BOOL bAlt   = (GetKeyState(VK_MENU) < 0);
  203.  
  204.             hr = spSite->TranslateAccelerator( &msg, (short)(bShift + (bCtrl << 1) + (bAlt << 2)) );
  205.             
  206. //            MessageBox( "tabbed me", 0, 0 );
  207. //            return m_ctlEdit.DefWindowProc( WM_CHAR, wParam, lParam );
  208.             return 0;
  209.         }
  210.  
  211.         bHandled = FALSE;
  212.  
  213.         return 0;
  214.     }
  215. */
  216.     // We must force the focus into our contained control when we ourselves receive
  217.     // the focus.
  218.  
  219.     LRESULT OnOleControlSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  220.     {
  221.         if( m_ctlEdit )
  222.             m_ctlEdit.SetFocus();
  223.  
  224.         return 0;
  225.     }
  226.  
  227.     // This message handler for WM_KILLFOCUS fires the controls Validate event
  228.     // The edit control assumes success for the validation event. Therefore,
  229.     // if the user does not implement the Validate event in his control, the
  230.     // control will behave just like a regular edit control.
  231.  
  232.     LRESULT OnSubclassKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  233.     {
  234.         int Length;
  235.         LPTSTR szText;
  236.         VARIANT_BOOL Valid = TRUE;        // assume success
  237.  
  238.         Length = m_ctlEdit.GetWindowTextLength();
  239.         szText = (LPTSTR)_alloca( ( Length + 1 ) * sizeof( TCHAR ) );
  240.  
  241.         m_ctlEdit.GetWindowText( szText, Length + 1 );
  242.  
  243.         CComBSTR Text = szText;
  244.  
  245.         Validate( Text, &Valid );
  246.  
  247.         if( Valid )
  248.         {
  249.             m_clrBackColor = m_clrCurrentBackColor;
  250.         }
  251.         else
  252.         {
  253.             m_clrCurrentBackColor = m_clrBackColor;
  254.             m_clrBackColor = m_clrErrorColor;
  255.         }
  256.  
  257.         FireViewChange();
  258.         
  259.         bHandled = FALSE;    // Call the default handler for WM_KILLFOCUS
  260.  
  261.         return 0;
  262.     }
  263.  
  264.     // We modify some of the code in this function to make sure that our 
  265.     // edit control is a multiline edit control with a 3D look (WS_EX_CLIENTEDGE)
  266.  
  267.     LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  268.     {
  269.         USES_CONVERSION;
  270.  
  271.         RECT rc;
  272.         GetWindowRect(&rc);
  273.         rc.right -= rc.left;
  274.         rc.bottom -= rc.top;
  275.         rc.top = rc.left = 0;
  276.  
  277.         // Make sure we destroy the child window if necessary ... or reset the
  278.         // child window's window handle to 0. A bug in an early version of ATL
  279.         // caused this window handle to NOT be reset to 0 when its parent 
  280.         // (the control window) is itself destroyed in the
  281.         // IOleInPlaceObject::UIDeactivate handler
  282.  
  283.         if( m_ctlEdit.m_hWnd )
  284.             if( IsWindow( m_ctlEdit ) )
  285.                 m_ctlEdit.DestroyWindow();
  286.             else
  287.                 m_ctlEdit.m_hWnd = 0;
  288.  
  289.         // Make sure that we create the Edit control with the appropriate window
  290.         // style bits set.
  291.  
  292.         m_ctlEdit.Create( m_hWnd, rc, NULL, WS_CHILD | WS_VISIBLE | 
  293.             ES_AUTOVSCROLL | ES_MULTILINE, WS_EX_CLIENTEDGE );
  294.  
  295.         // Initialize our edit control's window text with our Text property
  296.  
  297.         if( IsWindow( m_ctlEdit ) )
  298.             m_ctlEdit.SetWindowText( OLE2T( m_bstrText ) );
  299.  
  300.         OnFontChanged();
  301.  
  302.         return 0;
  303.     }
  304.  
  305.     // Our custom message handler to set the foreground and background
  306.     // colors for the edit control
  307.  
  308.     LRESULT OnCtlColorEdit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  309.     {
  310.         // Translate OLE_COLOR's back into Win32 COLORREF's
  311.  
  312.         COLORREF clrBack, clrFore;
  313.  
  314.         if( FAILED( OleTranslateColor( m_clrBackColor, m_hPalette, &clrBack ) ) )
  315.             OleTranslateColor( OLE_COLOR_WINDOW_BACKGROUND, m_hPalette, &clrBack );
  316.  
  317.         if( FAILED( OleTranslateColor( m_clrForeColor, m_hPalette, &clrFore ) ) )
  318.             OleTranslateColor( OLE_COLOR_WINDOW_TEXT, m_hPalette, &clrFore );
  319.  
  320.         ::SetTextColor( (HDC)wParam, clrFore );
  321.         ::SetBkColor( (HDC)wParam, clrBack );
  322.  
  323.         return (LRESULT)::CreateSolidBrush( clrBack );
  324.     }
  325.  
  326.     ///////////////////////////////////////////////////////////////////////////
  327.     // Persistence handlers
  328.  
  329.     // Handle the IPersistStreamInit::InitNew function call from our control's
  330.     // container. This function is called whenever a new instance of a control
  331.     // is created. We use this function to setup our control's ambient properties
  332.  
  333.     STDMETHOD(InitNew)()
  334.     {
  335.         OLE_COLOR clrBack, clrFore;
  336.  
  337.         // Setup default colors for our foreground and background colors
  338.  
  339.         m_clrBackColor = OLE_COLOR_WINDOW_BACKGROUND;
  340.         m_clrForeColor = OLE_COLOR_WINDOW_TEXT;
  341.  
  342.         if( SUCCEEDED( GetAmbientBackColor( clrBack ) ) )
  343.             m_clrBackColor = clrBack;
  344.  
  345.         if( SUCCEEDED( GetAmbientForeColor( clrFore ) ) )
  346.             m_clrForeColor = clrFore;
  347.  
  348.         // Our default error color is RED
  349.  
  350.         m_clrErrorColor = RGB( 255, 0, 0 );
  351.  
  352.         GetAmbientPalette( m_hPalette );
  353.  
  354.         // Get a copy of the container's ambient font object
  355.         // I don't implement a notification handler for what happens when the 
  356.         // container's ambient font CHANGES. This exercise is left to the reader.
  357.  
  358.         HRESULT hr;
  359.         CComPtr<IFont> Font;
  360.  
  361.         if( SUCCEEDED( GetAmbientFont( &Font ) ) )
  362.         {
  363.             // Make sure that our current font property is not holding onto 
  364.             // some font
  365.  
  366.             if( m_Font )
  367.                 m_Font.Release();
  368.  
  369.             hr = Font->Clone( &m_Font );
  370.  
  371.             if( FAILED( hr ) )
  372.                 return hr;
  373.         }
  374.         else
  375.         {
  376.             // You might want to add code to create your own font object
  377.             // if you can't get the ambient font from the container
  378.         }
  379.  
  380.         return S_OK;
  381.     }
  382.  
  383.     // We must handle the persistence of the Text and Font properties ourselves.
  384.     // This is due to the hybrid behavior of the control in design vs. run
  385.     // time. We do not wish to persist the run-time contents of the control!
  386.  
  387.     STDMETHOD(Load)(LPSTREAM pStm)
  388.     {
  389.         HRESULT hr;
  390.  
  391.         // Load the stock properties ( the color properties in this case )
  392.         // which have default persistance implementations.
  393.  
  394.         hr = IPersistStreamInitImpl<CAtlEditCtl>::Load( pStm );
  395.  
  396.         if( FAILED( hr ) )
  397.             return hr;
  398.  
  399.         // Create our Font object from persistant storage
  400.  
  401.         CComPtr< IFont > Font;
  402.  
  403.         if( SUCCEEDED( OleLoadFromStream( pStm, IID_IFont, (void**)&Font ) ) )
  404.             m_Font = Font;
  405.  
  406.         // Load our text property from persistant storage
  407.  
  408.         return m_bstrText.ReadFromStream( pStm );
  409.     }
  410.     
  411.     STDMETHOD(Save)(LPSTREAM pStm, BOOL fClearDirty)
  412.     {
  413.         HRESULT hr;
  414.         
  415.         hr = IPersistStreamInitImpl<CAtlEditCtl>::Save( pStm, fClearDirty );
  416.  
  417.         if( FAILED( hr ) )
  418.             return hr;
  419.         
  420.         // Save our font object to persistant storage
  421.     
  422.         // This is a nice demonstration of the CComQIPtr. In the constructor
  423.         // call, pObjStream QI's for the IID_IPersistStream interface from the
  424.         // m_Font pointer to the font object's IFont interface. Saves a line
  425.         // of code.
  426.  
  427.         CComQIPtr< IPersistStream, &IID_IPersistStream > pObjStream( m_Font );
  428.  
  429.         if( pObjStream )
  430.             OleSaveToStream( pObjStream, pStm );
  431.         
  432.         // Save our text property out to persistant storage
  433.  
  434.         return m_bstrText.WriteToStream( pStm );
  435.     }
  436.  
  437.     STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
  438.     {
  439.         IOleInPlaceObjectWindowlessImpl<CAtlEditCtl>::SetObjectRects(prcPos, prcClip);
  440.         int cx, cy;
  441.         cx = prcPos->right - prcPos->left;
  442.         cy = prcPos->bottom - prcPos->top;
  443.         ::SetWindowPos(m_ctlEdit.m_hWnd, NULL, 0,
  444.             0, cx, cy, SWP_NOZORDER | SWP_NOACTIVATE);
  445.         return S_OK;
  446.     }
  447.  
  448.     ///////////////////////////////////////////////////////////////////////////
  449.     // Property Handlers
  450.  
  451.     // Our implementation of the stock DISPID_TEXT property. Rather than
  452.     // store our property in a CComBSTR variable, we store our property
  453.     // in the actual Edit control window itself. However, where we store these
  454.     // properties depends on whether the control is in design time mode or run 
  455.     // time. If design time, we store it in our m_bstrText variable. If run
  456.     // time we store the variable in the actual edit control. This mimics
  457.     // the behavior of standard Text controls in VB.
  458.  
  459.     STDMETHOD(put_Text)( BSTR Text )
  460.     {
  461.         USES_CONVERSION;
  462.  
  463.         if( !IsWindow( m_ctlEdit ) )
  464.             m_bstrText = Text;
  465.         else
  466.             m_ctlEdit.SetWindowText( OLE2T( Text ) );
  467.  
  468.         FireViewChange();
  469.  
  470.         return S_OK;
  471.     }
  472.  
  473.     STDMETHOD(get_Text)( BSTR* pText )
  474.     {
  475.         if( !IsWindow( m_ctlEdit ) )
  476.             *pText = m_bstrText.Copy();
  477.         else
  478.             m_ctlEdit.GetWindowText( *pText );
  479.         
  480.         return S_OK;
  481.     }
  482.  
  483.     // Our custom error color property
  484.  
  485.     STDMETHOD(put_ErrorColor)( OLE_COLOR Color )
  486.     {
  487.         m_clrErrorColor = Color;
  488.         return S_OK;
  489.     }
  490.  
  491.     STDMETHOD(get_ErrorColor)( OLE_COLOR* pColor )
  492.     {
  493.         *pColor = m_clrErrorColor;
  494.         return S_OK;
  495.     }
  496.  
  497.     // Our implementation of the Font stock property
  498.  
  499.     STDMETHOD(putref_Font)( IFont* Font )
  500.     {
  501.         HFONT hFont;
  502.  
  503.         // Release our existing font if there is one (and we are in runtime mode)
  504.  
  505.         if( IsWindow( m_ctlEdit ) && m_Font != NULL )
  506.         {
  507.             hFont = m_ctlEdit.GetFont();
  508.  
  509.             if( hFont )
  510.                 m_Font->ReleaseHfont( hFont );
  511.  
  512.             m_Font.Release();
  513.         }
  514.  
  515.         // We need to clone this font before storing it in our property
  516.  
  517.         CComPtr<IFont> NewFont;
  518.  
  519.         if( SUCCEEDED( Font->Clone( &NewFont ) ) )
  520.             m_Font = NewFont;
  521.  
  522.         OnFontChanged;
  523.         FireViewChange();
  524.  
  525.         return S_OK;
  526.     }
  527.  
  528.     STDMETHOD(get_Font)( IFont** Font )
  529.     {
  530.         // Return a reference to our font object
  531.  
  532.         m_Font->AddRef();
  533.         *Font = m_Font;
  534.  
  535.         return S_OK;
  536.     }
  537.  
  538.     // We need to override the default implementation of put_BackColor
  539.     // so that we also set the additional variable m_clrCurrentBackColor
  540.  
  541.     STDMETHOD(put_BackColor)( OLE_COLOR Color )
  542.     {
  543.         m_clrCurrentBackColor = Color;
  544.         m_clrBackColor = Color;
  545.  
  546.         FireOnChanged( DISPID_BACKCOLOR );
  547.         FireViewChange();
  548.  
  549.         return S_OK;
  550.     }
  551.  
  552.     // Reflect the WM_KEYDOWN VK_TAB message to our container
  553. /*    
  554.     STDMETHOD(TranslateAccelerator)( LPMSG pMsg )
  555.     {
  556.         _ASSERTE( FALSE );
  557.  
  558.         if( pMsg->message == WM_KEYDOWN && 
  559.             static_cast< TCHAR >( pMsg->wParam ) == VK_TAB )
  560.         {
  561.             CComQIPtr <IOleControlSite, &IID_IOleControlSite> spSite(m_spClientSite);
  562.  
  563.             BOOL bShift = (GetKeyState(VK_SHIFT) < 0);
  564.             BOOL bCtrl  = (GetKeyState(VK_CONTROL) < 0);
  565.             BOOL bAlt   = (GetKeyState(VK_MENU) < 0);
  566.  
  567.             return spSite->TranslateAccelerator( pMsg, (short)(bShift + (bCtrl << 1) + (bAlt << 2)) );
  568.         }
  569.  
  570.         return S_FALSE;
  571.     }
  572. */
  573.     ///////////////////////////////////////////////////////////////////////////
  574.     // IViewObjectEx
  575.  
  576.     STDMETHOD(GetViewStatus)(DWORD* pdwStatus)
  577.     {
  578.         ATLTRACE(_T("IViewObjectExImpl::GetViewStatus\n"));
  579.         *pdwStatus = VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE;
  580.         return S_OK;
  581.     }
  582.  
  583. // IAtlEditCtl
  584. public:
  585.     HRESULT OnDraw(ATL_DRAWINFO& di);
  586.  
  587.     HFONT m_hFontPrev;
  588.     HPALETTE m_hPalette;
  589.  
  590.     OLE_COLOR m_clrCurrentBackColor;
  591.     OLE_COLOR m_clrErrorColor;
  592.     OLE_COLOR m_clrBackColor;
  593.     OLE_COLOR m_clrForeColor;
  594.  
  595.     CComBSTR m_bstrText;
  596.  
  597.     CComPtr<IFont> m_Font;        // A holder of this control's font object
  598. };
  599.  
  600. #endif //__ATLEDITCTL_H_
  601.